package com.tobeface.wechat.message;

import com.google.common.collect.Maps;
import com.tobeface.modules.lang.Ghost;
import com.tobeface.wechat.message.payload.*;

import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author loudyn
 */
public final class WeChatMessageBuilder {
    Map<String, Object> payloads = Maps.newHashMap();
    WeChatMessageVerb verb = WeChatMessageVerb.IGNORE;

    /**
     * @param sender
     * @return
     */
    public WeChatMessageBuilder from(String sender) {
        payload(WeChatMessagePayloads.SENDER_PAYLOAD, sender);
        return this;
    }

    /**
     * @param to
     * @return
     */
    public WeChatMessageBuilder to(String to) {
        payload(WeChatMessagePayloads.RECEIVER_PAYLOAD, to);
        return this;
    }

    /**
     * @param createTime
     * @return
     */
    public WeChatMessageBuilder on(String createTime) {
        payload(WeChatMessagePayloads.CREATETIME_PAYLOAD, createTime);
        return this;
    }

    /**
     * @param verb
     * @return
     */
    public WeChatMessageBuilder verb(String verb) {
        return verb(WeChatMessageVerb.valueOf(verb));
    }

    /**
     * @param verb
     * @return
     */
    public WeChatMessageBuilder verb(WeChatMessageVerb verb) {
        this.verb = verb;
        return this;
    }

    /**
     * @param name
     * @param val
     * @return
     */
    public WeChatMessageBuilder payload(String name, String val) {
        this.payloads.put(name, val);
        return this;
    }

    /**
     * @param payloads
     * @return
     */
    public WeChatMessageBuilder payloads(Map<String, Object> payloads) {
        this.payloads.putAll(payloads);
        return this;
    }

    /**
     * @return
     */
    public TextMessagePayloadBuilder text() {
        return new TextMessagePayloadBuilder(this);
    }

    /**
     * @return
     */
    public ImageMessagePayloadBuilder image() {
        return new ImageMessagePayloadBuilder(this);
    }

    OutImageMessagePayloadBuilder imageOut() {
        return new OutImageMessagePayloadBuilder(this);
    }

    /**
     * @return
     */
    public VoiceMessagePayloadBuilder voice() {
        return new VoiceMessagePayloadBuilder(this);
    }

    OutVoiceMessagePayloadBuilder voiceOut() {
        return new OutVoiceMessagePayloadBuilder(this);
    }

    /**
     * @return
     */
    public VideoMessagePayloadBuilder video() {
        return new VideoMessagePayloadBuilder(this);
    }

    OutVideoMessagePayloadBuilder videoOut() {
        return new OutVideoMessagePayloadBuilder(this);
    }

    /**
     * @return
     */
    public LocationMessagePayloadBuilder loc() {
        return new LocationMessagePayloadBuilder(this);
    }

    /**
     * @return
     */
    public LinkMessagePayloadBuilder link() {
        return new LinkMessagePayloadBuilder(this);
    }


    OutMusicMessagePayloadBuilder musicOut() {
        return new OutMusicMessagePayloadBuilder(this);
    }

    OutNewsMessagePayloadBuilder newsOut() {
        return new OutNewsMessagePayloadBuilder(this);
    }

    /**
     * @param payload
     * @param <T>
     * @return
     */
    public <T extends WeChatMessagePayloadBuilder> T payload(Class<T> payload) {
        Ghost<T> ghost = Ghost.me(payload);
        return ghost.born(this);
    }

    /**
     * @return
     */
    public WeChatMessage build() {
        return new WeChatMessage(this);
    }

    /**
     * @param xml
     * @return
     */
    public static WeChatMessageBuilder loadFrom(String xml) {
        return loadFromBytes(xml.getBytes(Charset.forName("UTF-8")));
    }

    /**
     * @param content
     * @return
     */
    public static WeChatMessageBuilder loadFromBytes(byte[] content) {
        Map<String, Object> payloads = WeChatMessagePayloadHelper.loads(content);
        return of().payloads(payloads);
    }

    /**
     * @param sender
     * @param receiver
     * @param createTime
     * @return
     */
    public static WeChatMessageBuilder of() {
        return new WeChatMessageBuilder();
    }

    /**
     * @param message
     * @return
     */
    public static WeChatMessageBuilder reply(WeChatMessage message) {
        long nowSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        return WeChatMessageBuilder.of().from(message.getReceiver())
                                        .to(message.getSender())
                                        .on(String.valueOf(nowSeconds));
    }

    /**
     * @param message
     * @return
     */
    public static TextMessagePayloadBuilder replyText(WeChatMessage message) {
        return reply(message).text();
    }

    /**
     * @param message
     * @return
     */
    public static OutImageMessagePayloadBuilder replyImage(WeChatMessage message) {
        return reply(message).imageOut();
    }

    /**
     * @param message
     * @return
     */
    public static OutNewsMessagePayloadBuilder replyNews(WeChatMessage message) {
        return reply(message).newsOut();
    }

    /**
     * @param message
     * @return
     */
    public static OutMusicMessagePayloadBuilder replyMusic(WeChatMessage message) {
        return reply(message).musicOut();
    }

    /**
     * @param message
     * @return
     */
    public static OutVoiceMessagePayloadBuilder replyVoice(WeChatMessage message) {
        return reply(message).voiceOut();
    }

    /**
     * @param message
     * @return
     */
    public static OutVideoMessagePayloadBuilder replyVideo(WeChatMessage message) {
        return reply(message).videoOut();
    }
}
